/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2009 - 2012 Luca Mingardi.
 *
 * This file is part of jeeObserver.
 *
 * JeeObserver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * JeeObserver is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
package jeeobserver.server.database;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import jeeobserver.server.database.DatabaseFile.DatabaseEntity;
import jeeobserver.settings.Settings;

class FileSettingsHandler {

	private static final String SETTINGS_FILE_NAME = "settings";

	private String path;

	private DatabaseFileBinary<SettingsEntity> fileSettings;

	public FileSettingsHandler(String path) throws IOException {

		this.path = path;

		//Create files (if not exists)
		this.fileSettings = new DatabaseFileBinary<SettingsEntity>(this.path + SETTINGS_FILE_NAME, SettingsEntity.class);
	}

	public synchronized Settings loadSettings() throws IOException, ClassNotFoundException {
		this.fileSettings.reset();
		SettingsEntity settingsEntity = (SettingsEntity) this.fileSettings.read();
		if (settingsEntity == null) {
			this.updateSettings(new Settings());
			this.fileSettings.reset();
			return ((SettingsEntity) this.fileSettings.read()).getSettings();
		}

		return settingsEntity.getSettings();
	}

	public synchronized void updateSettings(Settings settings) throws IOException {
		this.fileSettings.reset();
		this.fileSettings.write(new SettingsEntity(settings));
	}

	public synchronized void close() throws IOException {
		this.fileSettings.close();
	}

	static class SettingsEntity implements DatabaseEntity {

		private static final long serialVersionUID = 40L;

		private Settings settings;

		public SettingsEntity(Settings settings) {
			this.settings = settings;
		}

		public SettingsEntity(ByteBuffer buffer) throws IOException, ClassNotFoundException {
			this(buffer.array());
		}

		public SettingsEntity(byte[] bytes) throws IOException, ClassNotFoundException {
			this.settings = (Settings) (new ObjectInputStream(new ByteArrayInputStream(bytes))).readObject();
		}

		public byte[] getBytes() {

			try {
				final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				final ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);

				objectOutputStream.writeObject(this.settings);
				objectOutputStream.flush();
				objectOutputStream.close();

				final byte[] bytes = byteArrayOutputStream.toByteArray();
				byteArrayOutputStream.flush();
				byteArrayOutputStream.close();

				return bytes;
			} catch (IOException ex) {
				ex.printStackTrace(System.out);
			}

			return null;
		}

		public int getSize() {
			return (getBytes().length);
		}

		public Settings getSettings() {
			return settings;
		}
	}
}
